package cn.geminis.auth.server.config;

import cn.geminis.auth.server.service.JwtTokenEnhancer;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;

import java.util.ArrayList;

/**
 * @author puddi
 */
@Configuration
@EnableAuthorizationServer
@AllArgsConstructor
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    private final AuthenticationManager authenticationManager;
//    private final UserDetailsService userDetailsService;
    private final JwtTokenEnhancer jwtTokenEnhancer;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        //用来配置令牌端点(Token Endpoint)的安全与权限访问。
        security
//                .tokenKeyAccess("permitAll()")
//                .checkTokenAccess("permitAll()")
//                .accessDeniedHandler(new AccessDeniedHandlerImpl())
                //允许表单传入 client_id client_secret进行认证
                .allowFormAuthenticationForClients();
    }

    /**
     * 认证配置
     *
     * @param endpoints endpoints
     * @throws Exception endpoints
     */
    @Override
    public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        var enhancerChain = new TokenEnhancerChain();
        var delegates = new ArrayList<TokenEnhancer>();
        delegates.add(jwtTokenEnhancer);
//        delegates.add(accessTokenConverter());
        enhancerChain.setTokenEnhancers(delegates);

        //用来配置授权以及令牌（Token）的访问端点和令牌服务（比如：配置令牌的签名与存储方式）
        endpoints
                .authenticationManager(this.authenticationManager)
//                .userDetailsService(userDetailsService)
//                .accessTokenConverter(accessTokenConverter())
                .tokenEnhancer(enhancerChain);
//                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
        //token 存储
//                .tokenStore(tokenStore());
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //内存中配置客户端信息
        //用来配置客户端详情信息，一般使用数据库来存储或读取应用配置的详情信息
        clients.inMemory().withClient("gateway")
                .authorizedGrantTypes("authorization_code")
                .scopes("all")
                // // secret密码配置从 Spring Security 5.0开始必须以 {加密方式}+加密后的密码 这种格式填写
                //        /*
                //         *   当前版本5新增支持加密方式：
                //         *   bcrypt - BCryptPasswordEncoder (Also used for encoding)
                //         *   ldap - LdapShaPasswordEncoder
                //         *   MD4 - Md4PasswordEncoder
                //         *   MD5 - new MessageDigestPasswordEncoder("MD5")
                //         *   noop - NoOpPasswordEncoder
                //         *   pbkdf2 - Pbkdf2PasswordEncoder
                //         *   scrypt - SCryptPasswordEncoder
                //         *   SHA-1 - new MessageDigestPasswordEncoder("SHA-1")
                //         *   SHA-256 - new MessageDigestPasswordEncoder("SHA-256")
                //         *   sha256 - StandardPasswordEncoder
                //         */
                .secret("{noop}123456")
                .redirectUris("http://localhost/ui/portal")
                .accessTokenValiditySeconds(3600)
                .refreshTokenValiditySeconds(86400);
    }

//    @Bean
//    public JwtAccessTokenConverter accessTokenConverter() {
//        var jwtAccessTokenConverter = new JwtAccessTokenConverter();
//        jwtAccessTokenConverter.setKeyPair(keyPair());
//        return jwtAccessTokenConverter;
//    }
//
//    @Bean
//    public KeyPair keyPair() {
//        //从classpath下的证书中获取秘钥对
//        var keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("gemini.jks"), "12345678".toCharArray());
//        return keyStoreKeyFactory.getKeyPair("gemini", "12345678".toCharArray());
//    }

//    @Bean
//    public UserDetailsService userDetails() {
//        var admin = User.withUsername("admin")
//                //,默认BCryptPasswordEncoder 更多实现 org.springframework.security.crypto.password.PasswordEncoder
//                //可查看该接口的实现
//                // password  Spring Security 5.0开始必须以 {加密方式}+加密后的密码 这种格式填写
//                .password("{bcrypt}$2a$10$ZlFDDZMkZ9P7Yb4BsZ50ZueNzn7yM3GTJD97M5cJMWDu4oKr1Lsuq")
//                .roles("ADMIN", "USER")
//                .build();
//        var user = User.withUsername("user")
//                .password("{bcrypt}" + new BCryptPasswordEncoder().encode("123456"))
//                .roles("USER")
//                .build();
//        //内存用户管理器
//        var userDetailsManager = new InMemoryUserDetailsManager();
//        userDetailsManager.createUser(admin);
//        userDetailsManager.createUser(user);
//        return userDetailsManager;
//    }

}
